package com.weiiew.backend.operationUtils;


import com.weiiew.backend.entity.enums.ExecutorState;
import com.weiiew.backend.entity.status.ExecutorStatus;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.helpers.MessageFormatter;
import org.springframework.messaging.simp.SimpMessagingTemplate;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author 魏锴
 * @since 2025/5/3
 */
@Slf4j
public class ExecutorCommunicationTool {
    private final SimpMessagingTemplate template;
    private final String channel;
    private long lastSendTime = 0;
    private ExecutorStatus status = new ExecutorStatus();
    private final ExecutorService asyncSender = Executors.newSingleThreadExecutor();
    /**
     * 构造方法
     */
    public ExecutorCommunicationTool() {
        this.template = null;
        this.channel = null;
    }

    /**
     * 构造方法
     *
     * @param template SimpMessagingTemplate实例
     * @param channel  频道
     */
    public ExecutorCommunicationTool(SimpMessagingTemplate template, String channel) {
        this.template = template;
        this.channel = channel;
    }

    /**
     * 发送消息
     *
     * @param state        当前执行器状态
     * @param currentIndex 当前执行的操作index
     * @param message      需要发送的消息，含有{}
     * @param args         需要填充进message的变量
     */
    public void sendMessage(ExecutorState state, int currentIndex, String message, Object... args) {
        String formatted = MessageFormatter.arrayFormat(message, args).getMessage();
        sendMessage(state, currentIndex, formatted);
    }

    /**
     * 发送消息
     *
     * @param state        当前执行器状态
     * @param currentIndex 当前执行的操作index
     * @param message      需要发送的消息
     */
    public void sendMessage(ExecutorState state, int currentIndex, String message) {
        log.info("当前执行器状态{}, {}", state, message);
        if (template == null || channel == null) return;
        status.addMessage(message);
        if (System.currentTimeMillis() - lastSendTime >= 100) {
            innerSendMessage(state, currentIndex);
        }
    }

    /**
     * 强制发送消息
     *
     * @param state        当前执行器状态
     * @param currentIndex 当前执行的操作index
     * @param message      需要发送的消息，含有{}
     * @param args         需要填充进message的变量
     */
    public void focusedSendMessage(ExecutorState state, int currentIndex, String message, Object... args) {
        String formatted = MessageFormatter.arrayFormat(message, args).getMessage();
        focusedSendMessage(state, currentIndex, formatted);
    }

    /**
     * 强制发送消息
     *
     * @param state        当前执行器状态
     * @param currentIndex 当前执行的操作index
     * @param message      需要发送的消息
     */
    public void focusedSendMessage(ExecutorState state, int currentIndex, String message) {
        log.info("当前执行器状态{}, {}", state, message);
        if (template == null || channel == null) return;
        status.addMessage(message);
        innerSendMessage(state, currentIndex);
    }

    /**
     * 真正发送消息的方法
     *
     * @param state        当前状态
     * @param currentIndex 当前index
     */
    private synchronized void innerSendMessage(ExecutorState state, int currentIndex) {
        lastSendTime = System.currentTimeMillis();
        status.setState(state);
        status.setCurrentIndex(currentIndex);
        ExecutorStatus temp = status; // 防止status被修改
        status = new ExecutorStatus();
        // 异步发送消息, 防止阻塞
        asyncSender.submit(() -> {
            assert template != null;
            assert channel != null;
            template.convertAndSend(channel, temp);
        });
    }
}
